from PyQt4 import QtGui, QtCore, QtOpenGL

import osg2 as osg

class OpenSGTreeModel(QtCore.QAbstractItemModel):
   def __init__(self, rootNode, parent=None):
      QtCore.QAbstractListModel.__init__(self, parent)
      self.mRootNode = rootNode
      #print "RootNode [%s] [%s]" % (self.mRootNode.getId(), osg.getName(self.mRootNode))
      self.mObjectDict = {}
      self.mObjectDict[self.mRootNode.getId()] = self.mRootNode

   def index(self, row, column, parent):
      #print "SGModel::index() [%s][%s][%s]" % (row, column, parent.internalId())
      #print "SGModel::index()"
      #print "   parent: [%s][%s][%s]" % (parent.row(), parent.column(), parent.internalId())
      c = self.columnCount(parent)
      if (row < 0 or column < 0 or column >= c):
         return QtCore.QModelIndex()

      # Top level items
      if not parent.isValid():
         #print "Trying to create an invalid index, must be for root."
         #assert row == 1
         fcid = self.mRootNode.getId()
         self.mObjectDict[fcid] = self.mRootNode
         #index = self.createIndex(row, column, fcid)
         index = self.createIndex(0, column, fcid)
         #print "1   index: [%s][%s][%s]" % (index.row(), index.column(), index.internalId())
         return index

      # Children
      parent_node = self.mObjectDict[parent.internalId()]
      child_node = parent_node.getChild(row)
      fcid = child_node.getId()
      self.mObjectDict[fcid] = child_node
      index = self.createIndex(row, column, fcid)
      #print "2   index: [%s][%s][%s]" % (index.row(), index.column(), index.internalId())
      return index

   def parent(self, child):
      child_fcid = child.internalId()
      #print "parent() for [%s]" % (child_fcid)
      #print "   [%s][%s][%s]" % (child.row(), child.column(), child.model())
      
      child_node = self.mObjectDict[child_fcid]
      if child_node == self.mRootNode:
         #print "index() ROOT NODE"
         return QtCore.QModelIndex()
      if not child.isValid():
         return QtCore.QModelIndex()
      child_fcid = child.internalId()
      if child_fcid < 0:
         return QtCore.QModelIndex()
      child_node = self.mObjectDict[child_fcid]
      parent_node = child_node.getParent()
      #print "   child: [%s] parent: [%s]" % (osg.getName(child_node), osg.getName(parent_node))
      #print "   [%s] [%s]" % (child_node.getNChildren(), parent_node.getNChildren())
      #print "   parent: [%s]" % (parent_node)
      return self.indexHelper(parent_node, 0)

   def indexHelper(self, node, column):
      if node is None:
         return QtCore.QModelIndex()
      if None == node:
         return QtCore.QModelIndex()
      if node == self.mRootNode:
         #print "indexHelper() ROOT NODE"
         return QtCore.QModelIndex()

      fcid = node.getId()

      # XXX: Hack around the fact that None is not the same as OSG::NullFC
      root_fcid = self.mRootNode.getId()
      #print "index:Helper [%s][%s][%s]" % (fcid, osg.getName(node), root_fcid)
      if node == self.mRootNode or fcid == root_fcid:
         index = self.createIndex(0, column, fcid)
         #print "3.1   index: [%s][%s][%s]" % (index.row(), index.column(), index.internalId())
         return index


      parent_node = node.getParent()
      
      if None != parent_node:
         child_num = parent_node.findChild(node)
         index = self.createIndex(child_num, column, fcid)
         #print "3   index: [%s][%s][%s]" % (index.row(), index.column(), index.internalId())
         return index
      else:
         # This should get index of node into list of root nodes.
         #child_num = self.mRootNode.findChild(node)
         index = self.createIndex(0, column, fcid)
         #print "4   index: [%s][%s][%s]" % (index.row(), index.column(), index.internalId())
         return index

   def data(self, index, role=QtCore.Qt.DisplayRole):
      #print "SGModel::data() [%s] [%s]" % (index.row(), index.column())
      if not index.isValid():
         #print "SGModel::data() NOT VALID"
         return QtCore.QVariant()
      else:
         childItem = self.mObjectDict[index.internalId()]
         #print "SGModel::data() [%s] [%s] [%s]" % (index.internalId(), childItem, osg.getName(childItem))
         if childItem is None:
            return QtCore.QVariant()
         
         if role == QtCore.Qt.DisplayRole or role == QtCore.Qt.EditRole:
            return QtCore.QVariant(str(osg.getName(childItem)))
         elif role == QtCore.Qt.UserRole:
            return childItem
      return QtCore.QVariant()

   def setData(self, index, value, role):
      if not index.isValid():
         return False
      else:
         childItem = self.mObjectDict[index.internalId()]
         if childItem is not None:
            if role == QtCore.Qt.EditRole:
               osg.setName(childItem, str(value.toString()))
               self.emit(QtCore.SIGNAL("dataChanged(QModelIndex,QModelIndex)"), index, index)
               self.emit(QtCore.SIGNAL("dataChanged(int)"), index.row())
               return True
      return False


   def columnCount(self, parent):
      return 1;

   def flags(self, index):
      #if not index.isValid():
      #   return QtCore.Qt.ItemIsEnabled
      return QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsEditable
      #return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable

   def rowCount(self, parent=QtCore.QModelIndex()):
      if parent.isValid():
         #parent_node = self.item(parent)
         parent_node = self.mObjectDict[parent.internalId()]
         if parent_node is not None:
            return parent_node.getNChildren()
      #print "SGModel::rowCount()"
      #print "   [%s][%s][%s]" % (parent.row(), parent.column(), parent.internalId())
      num_of_roots = 1
      return num_of_roots


   def insertRows(self, row, count, parent):
      self.beginInsertRows(QtCore.QModelIndex(), row, row + count - 1)
      #for i in xrange(count):
      #   new_element = ET.SubElement(self.mElement, "cluster_node", name="NewNode", hostname="NewNode")
      #   new_node = ClusterNode(new_element)
      #   self.mNodes.insert(row, new_node);
      #self.refreshConnections()
      self.endInsertRows()
      #self.emit(QtCore.SIGNAL("rowsInserted(int, int)"), row, count)
      return True

   def removeRows(self, row, count, parent):
      self.beginRemoveRows(QtCore.QModelIndex(), row, row + count - 1)
      #self.emit(QtCore.SIGNAL("rowsAboutToBeRemoved(int, int)"), row, count)
      #for i in xrange(count):
      #   node = self.mNodes[row]
      #
      #   # Remove node's element from XML tree.
      #   self.mElement.remove(node.mElement)
      #   # Remove node data structure
      #   self.mNodes.remove(node)
      self.endRemoveRows()
      return True

